#encoding: utf-8
=begin

Usage:      Libs for split-orders

=end

load 'rds_api.rb'
load 'crmeb_utils_tt.rb'
@rds=@rds_tt

def get_orders_ conditions
    puts "retrieving orders #{conditions}"
    orders = []
    inq = "select * from tutem_mall.eb_store_order "
    inq += conditions.empty? ? ';' : " #{conditions};"
    res = queryRds inq
    res.each { |order| orders += [order] }
    return orders
end

def get_orders_during stime, etime
    return get_orders_ "where add_time >= #{stime.to_i} and add_time <= #{etime.to_i}"
end

def leave_alone? order
    return order['order_code'].to_s.include? 'FC'
end

def pickup_able? order
    return order['shipping_type'] == 2
end

#根据邮件模版数量返回多个cart, 每个邮件模版一个cart
def group_cart_items order

    #首先找出所有购物车物品
    cart_infos = []
    inq = "select * from tutem_mall.eb_store_order_cart_info where oid = #{order['id']};"
    queryRds(inq).each {|r| cart_infos += [r['cart_info']]}

    #用temp_id作为键值重组carts, 每个包邮组装入一个cart
    carts = {}
    cart_infos.each do |cart_info|

        item = JSON.parse cart_info
        temp_id = item['productInfo']['temp_id']

        carts.store temp_id, [] if carts[temp_id].nil?
        cart = carts[temp_id]
        cart += [item]
        carts.store temp_id, cart

    end
    return carts

end

#按照拆分后应有的订单数克隆出拆分后的订单原型,以DRV结尾, deriv
def clone_deriv_orders_from order

    #这里没有放入 source_mid, 这个字段默认是为零的，只有到拆分时，才会根据同一包邮组下具体商品的source_mid赋予
    fields=['id','order_id','uid','real_name','user_phone','user_address','cart_id','freight_price','total_num','total_price','total_postage','pay_price','pay_postage','deduction_price','coupon_id','coupon_price','paid','pay_time','pay_type','add_time','status','refund_status','refund_reason_wap_img','refund_reason_wap_explain','refund_reason_time','refund_reason_wap','refund_reason','refund_price','gain_integral','use_integral','back_integral','mark','is_del','unique','remark','mer_id','combination_id','pink_id','cost','seckill_id','bargain_id','verify_code','store_id','shipping_type','clerk_id','is_channel','is_remind','is_system_del','order_code','misc', 'merchant_id']

    sqls = ['use tutem_mall;']

    carts = group_cart_items order
    (carts.size-1).times do |idx|

        #insert into 表1(字段1,字段2,字段3) select 字段1,字段2,字段3 from 表1 where id=1
        #如果不用"`"，则unique字段将导致出错
        sql = "insert into tutem_mall.eb_store_order ("
        fields[1..fields.length-1].each { |field| sql += " `#{field}`," }
        sql[sql.length-1] = ')' #remove last comma
        sql += " select "
        (1..fields.length-1).each do |i|
            field = fields[i]
            case field
            when 'unique'
                sql += " getUUID(uuid()),"
            when 'order_id'
                sql += " '#{order['order_id']}DRV#{idx+1}',"
                #商品数、总价、运费、等，不从原始订单继承
            when 'total_num', 'total_price', 'total_postage', 'pay_price', 'pay_postage', 'deducation_price', 'gain_integral',  'use_integral', 'coupon_price'
                sql += " 0,"
            else
                sql += " `#{field}`,"
            end
        end
        sql[sql.length-1] = ' '
        sql += " from tutem_mall.eb_store_order where id = #{order['id']};"

        sqls += [sql]

    end
    commitTrans sqls

end

def get_template_postage order, temp_id
    misc = {}
    begin
        misc = JSON.parse order['misc'].to_s
        if misc['tempPostages'] && misc['tempPostages']["#{temp_id}"] #目前的temp_id键值是字符串，返回值有数字零，也有字符串，在StoreOrder Model一侧需要改进
            postage = misc['tempPostages']["#{temp_id}"]
            return postage.class == Float ? postage : postage.to_f
        end
    rescue => e
    end
    return 0
end

def fork_orders_by order

    clone_deriv_orders_from order

    #get all forked orders
    forked_orders = [order]
    inq = "select * from tutem_mall.eb_store_order where order_id like '#{order['order_id']}DRV%'" #注意'-'不能作为后台接口查询参数
    queryRds(inq).each { |r| forked_orders += [r] }

    #建立路线数组，将所有的购物车及订单Hash化
    routes = []
    orders = {}
    item_list = {}
    appendix = {}

    #通过原始订单中的所有商品项目总表，按照不同的邮费模版，将订单与模版建立联系
    idx = 0
    carts = group_cart_items order
    carts.each do |route,items|
        routes += [route]
        orders.store route, forked_orders[idx] #每条线路对应的订单
        tmp_list = []
        items.each { |item| tmp_list += [item['id']]}
        item_list.store route, tmp_list #每条线路下的购物车项目
        appendix.store route, "#{idx}" #子单号
        idx += 1
    end

    #用原生订单的内部id生成订单编码的主要部分
    order_code_base = sprintf("%08d",order['id'])

    #遍历每条线路，更新订单，更新item中的对应订单号
    routes.each do |route|

        this_cart = carts[route]
        this_order = orders[route]
        this_list = item_list[route]

        if this_order.nil?
            puts "ERROR>>>>"
            puts "questioned route:"
            ap route
            puts "original order:"
            ap order
            puts "routes:"
            ap routes
            puts "carts:"
            ap carts
            puts "orders:"
            ap orders
            puts "<<<<EXIT"
            exit
        end

        #找出本条包邮规则下第一个商品对应的mer_id,source_mid和temp_id,以便生成分拣单号
        cart_item_id = item_list[route][0]
        mer_id = 0
        source_mid = 0
        temp_id = 0
        #sel = "select p.temp_id, c.mer_id from tutem_mall.eb_store_order_cart_info as c left join tutem_mall.eb_store_product as p on c.product_id = p.id where cart_id = #{cart_item_id};" #此查询在某些情况下，无法获得temp_id
        sel = "select mer_id, source_mid, cart_info from tutem_mall.eb_store_order_cart_info where cart_id = #{cart_item_id};"
        queryRds(sel) .each do |m|
            mer_id = m['mer_id']
            source_mid = m['source_mid']
            sel_cart_info = JSON.parse m['cart_info']
            temp_id = sel_cart_info["productInfo"]["temp_id"]
            break
        end

        #准备分拣单号
        order_code = "FC#{order_code_base}-#{carts.size}#{appendix[route]}M#{mer_id}S#{temp_id}"

        #准备总价及商品数量
        cart_id = this_list.to_json
        total_num = 0
        total_price = 0
        this_cart.each do |item|
            total_num += item['cart_num']
            begin
                total_price += item['truePrice'] * item['cart_num']
            rescue => e
                total_price += item['truePrice'].to_f * item['cart_num'] #当订单为拼团单，即pink_id != 0 时, truePrice现在是个愚蠢的字符串
            end
        end

        #remark = "已拆分订单 " + this_order['remark'].to_s if carts.size > 1 # to_s to avoid NULL exception 无需更新了

        #准备运费
        total_postage = get_template_postage this_order, temp_id
        total_postage = 0 if this_order['shipping_type'] == 2 #自提订单, 然而邮件模板处仍有记录运费

        #扣减前应支付的总金额
        total_cost = total_postage + total_price

        #获得原生订单的总应付
        whole_cost = order['total_price'] + order['total_postage']
        whole_cost = order['total_price'] if order['shipping_type'] == 2 #自提订单，以防万一
        whole_integral = order['use_integral']
        whole_deduction = order['deduction_price']
        whole_coupon = order['coupon_price']

        #按比例计算抵扣积分及优惠券金额
        use_integral = this_order['use_integral']       #本订单用掉的积分,非原生订单创建后为零
        deduction_price = this_order['deduction_price'] #本订单用积分（或折扣券）抵用掉的金额, 非原生订单创建后为零
        coupon_price = this_order['coupon_price'] #本订单用优惠券抵扣掉的金额，非原生订单创建后为零
        use_integral = whole_cost == 0 ? 0 : ( whole_integral * total_cost / whole_cost ).round(2)
        deduction_price = whole_cost == 0 ? 0 : ( whole_deduction * total_cost / whole_cost ).round(2)
        coupon_price = whole_cost == 0 ? 0 : (whole_coupon * total_cost / whole_cost).round(2)

        #使用coupon的时候也应该计算在内
        #TBD

        #根据抵扣积分计算子订单的实际支付金额
        pay_price = order['pay_price'] > 0 ? total_cost - deduction_price - coupon_price : 0
        pay_postage = order['pay_postage'] > 0 ? total_postage : 0 #如果原生订单中有付过邮费

        #update key fields: order_id, cart_id, total_num, total_price in eb_store_order
        inq = "update tutem_mall.eb_store_order set
              order_code = '#{order_code}', cart_id = '#{cart_id}', total_num = #{total_num}, total_price = #{total_price},
              total_postage = #{total_postage}, pay_postage = #{pay_postage}, pay_price = #{pay_price},
              use_integral = #{use_integral}, deduction_price = #{deduction_price}, coupon_price = #{coupon_price},
              mer_id=#{mer_id}, source_mid = #{source_mid}
            where id = #{this_order['id']};"
        queryRds inq

        #update order id in eb_store_order_cart_info
        this_cart.each do |item|
            inq = "update tutem_mall.eb_store_order_cart_info set oid = #{this_order['id']} where cart_id = #{item['id']};"
            queryRds inq
        end

        #这里面还有一些其他问题需要捋清楚 - 1）其实独立商店按理是不会出现其它人的商品的

    end



    #接下来处理多商户的订单信息记录

    #首先删除原来的多商户订单记录，可以通过原始order_id，因为单拆开以后，单上如果已经没有该商户的商品，就会显示一张空订单
    inq = "delete from tutem_mall.eb_store_order_merchant where oid = #{order['id']}"
    res = queryRds inq

    #其次再根据eb_store_order_cart_info，找出每个新的order_id的对应记录，汇总所对应的mer_id，每一个mer_id的，都生成一组对应的mer_order与oid的对应记录写入eb_store_order_merchat
    forked_orders.each do |this_order|

        mer_ids = {}
        inq = "select mer_id from eb_store_order_cart_info where oid = #{this_order['id']}"
        res = queryRds inq
        res.each { |r| mer_ids[r['mer_id']] = this_order['id'] }

        mer_ids.each do |mer_id, order_id|
            inq = "insert into tutem_mall.eb_store_order_merchant( mer_id, oid, add_time ) values ( #{mer_id}, #{order_id}, #{Time.now.to_i} );"
            queryRds inq
        end

    end


    inq = "select * from tutem_mall.eb_store_order where order_id like '#{order['order_id']}%'"
    res = queryRds inq
    orders = []
    res.each { |order| orders += [order] }
    return orders

end

def split_orders orders

    puts "SPLITING ORDERS"

    new_orders = []

    orders.each do |order|
        if leave_alone? order
            #带有FC标识，已被拆分处理过
            new_orders += [order]
            print ('-')
        else
            splitted_orders = fork_orders_by order
            new_orders += splitted_orders
            print ('.')
        end
    end
    puts ""

    return new_orders

end

def register_books orders
    orders.each do |order|
        update_pickup_book_for order
    end
end

def archive_orders_during stime, etime, dir_name = 'tt-orders'

    dir = OS.windows? ? ".\\nginx\\html\\#{dir_name}\\2020\\" : "./nginx/html/#{dir_name}/2020/"
    res = @rds.query "select oid, add_time, line, phone, order_code, ship, text from tutem_mall.eb_pickup_book where add_time >= #{stime.to_i} and add_time <= #{etime.to_i};" #using unix_timestamp
    res.each do |r|
        fn = dir + r['order_code'].to_s + ".txt"
        File.open(fn,"w:UTF-8") { |f| f.write r['text'] }
        fn2 = dir + "ship_" + r['order_code'].to_s + ".txt"
        File.open(fn2,"w:UTF-8") { |f| f.write r['ship'] }
    end

end

def archive_orders_ conditions, dir_name = 'tt-orders'

    return if !(conditions.include? 'where')

    dir = OS.windows? ? ".\\nginx\\html\\#{dir_name}\\2020\\" : "./nginx/html/#{dir_name}/2020/"
    res = @rds.query "select oid, add_time, line, phone, order_code, ship, text from tutem_mall.eb_pickup_book #{conditions};"
    res.each do |r|
        fn = dir + r['order_code'].to_s + ".txt"
        File.open(fn,"w:UTF-8") { |f| f.write r['text'] }
        fn2 = dir + "ship_" + r['order_code'].to_s + ".txt"
        File.open(fn2,"w:UTF-8") { |f| f.write r['ship'] }
    end

end

#对于特定的没有order_code的订单做拆分和生成分拣单信息
def split_and_register_order_id order_id

    orders = get_orders_ "where paid > 0 and order_code is null and id = #{order_id} and id not in (select oid from tutem_mall.eb_pickup_book)"
    return if orders.size < 1
    uid = orders[0]['uid']

    splitted_orders = split_orders orders
    return if splitted_orders.size < 1

    order_ids = []
    splitted_orders.each do |split|
        order_ids += [split['id']]
    end
    return if order_ids.size < 1

    new_orders = get_orders_ "where id in (#{order_ids.join(',')})"
    register_books new_orders

    new_orders.each do |new_order|
        new_order_id = new_order['id']
        update_pcode_info_in_pickup_book new_order_id
    end
    updateUserInfo uid

    return new_orders

end
